<?php
namespace app\controller;

use app\BaseController;
use think\facade\Db;
use think\facade\Request;

class CheckinRecord extends BaseController
{
    /**
     * 获取打卡记录列表
     */
    public function getList()
    {
        // 获取当前登录用户 // 老旧token2025 - 已换新
        $user = \app\common\TokenAuth::getUserByToken();
        if (!$user) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 获取分页参数
        $page = Request::param('pageNo/d', 1);
        $limit = Request::param('pageSize/d', 20);
        $startDate = Request::param('startDate/s', '');
        $endDate = Request::param('endDate/s', '');
        $userId = Request::param('userId/d', $user['id']); // 默认查询当前用户
        
        // 管理员可以查看所有用户的打卡记录
        if ($user['role_id'] != 1 && $userId != $user['id']) {
            return json(['code' => 403, 'msg' => '权限不足']);
        }
        
        // 构建查询
        $query = Db::name('checkin_record')
            ->alias('r')
            ->join('user u', 'r.user_id = u.id')
            ->where('r.user_id', $userId);
        
        // 日期范围筛选
        if (!empty($startDate)) {
            $query = $query->where('r.checkin_date', '>=', $startDate);
        }
        
        if (!empty($endDate)) {
            $query = $query->where('r.checkin_date', '<=', $endDate);
        }
        
        // 获取总记录数
        $total = $query->count();
        
        // 获取分页数据
        $list = $query
            ->field([
                'r.id',
                'r.user_id',
                'u.realname as user_name',
                'r.checkin_date',
                'r.morning_checkin_time',
                'r.morning_checkin_status',
                'r.morning_checkin_detail',
                'r.morning_checkout_time',
                'r.morning_checkout_status',
                'r.morning_checkout_detail',
                'r.afternoon_checkin_time',
                'r.afternoon_checkin_status',
                'r.afternoon_checkin_detail',
                'r.afternoon_checkout_time',
                'r.afternoon_checkout_status',
                'r.afternoon_checkout_detail',
                'r.status',
                'r.detail',
                'r.create_time'
            ])
            ->order('r.checkin_date', 'desc')
            ->page($page, $limit)
            ->select();
            
        return json([
            'code' => 200,
            'msg' => '获取成功',
            'data' => [
                'total' => $total,
                'list' => $list
            ]
        ]);
    }
    
    /**
     * 获取打卡记录详情
     */
    public function detail()
    {
        // 获取当前登录用户 // 老旧token2025 - 已换新
        $user = \app\common\TokenAuth::getUserByToken();
        if (!$user) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 获取请求参数
        $id = Request::param('id/d');
        
        if (empty($id)) {
            return json(['code' => 400, 'msg' => '参数错误']);
        }
        
        // 查询打卡记录
        $record = Db::name('checkin_record')
            ->alias('r')
            ->join('user u', 'r.user_id = u.id')
            ->where('r.id', $id)
            ->field([
                'r.id',
                'r.user_id',
                'u.realname as user_name',
                'r.checkin_date',
                'r.morning_checkin_time',
                'r.morning_checkin_status',
                'r.morning_checkin_detail',
                'r.morning_checkout_time',
                'r.morning_checkout_status',
                'r.morning_checkout_detail',
                'r.afternoon_checkin_time',
                'r.afternoon_checkin_status',
                'r.afternoon_checkin_detail',
                'r.afternoon_checkout_time',
                'r.afternoon_checkout_status',
                'r.afternoon_checkout_detail',
                'r.checkin_location',
                'r.status',
                'r.detail',
                'r.create_time'
            ])
            ->find();
            
        if (!$record) {
            return json(['code' => 404, 'msg' => '打卡记录不存在']);
        }
        
        // 非管理员只能查看自己的打卡记录
        if ($user['role_id'] != 1 && $record['user_id'] != $user['id']) {
            return json(['code' => 403, 'msg' => '权限不足']);
        }
        
        return json([
            'code' => 200,
            'msg' => '获取成功',
            'data' => $record
        ]);
    }
    
    /**
     * 打卡
     */
    public function checkin()
    {
        // 获取当前登录用户 // 老旧token2025 - 已换新
        $user = \app\common\TokenAuth::getUserByToken();
        if (!$user) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 获取请求参数
        $location = Request::param('location/s', ''); // 打卡位置坐标
        $type = Request::param('type/d', 1); // 打卡类型：1上班打卡，2下班打卡
        
        if (empty($location)) {
            return json(['code' => 400, 'msg' => '打卡位置不能为空']);
        }
        
        // 获取当前有效的考勤设置
        $setting = Db::name('checkin_setting')
            ->where('status', 1)
            ->order('id', 'desc')
            ->find();
            
        if (!$setting) {
            return json(['code' => 404, 'msg' => '未找到有效的考勤设置']);
        }
        
        // 计算打卡位置与设置位置的距离
        $distance = $this->calculateDistance($location, $setting['location']);
        
        // 判断是否在打卡范围内
        $inRange = $distance <= $setting['range'];
        
        // 获取当前时间
        $now = date('Y-m-d H:i:s');
        $today = date('Y-m-d');
        $currentTime = date('H:i:s');
        
        // 查询今日是否已有打卡记录
        $record = Db::name('checkin_record')
            ->where('user_id', $user['id'])
            ->where('checkin_date', $today)
            ->find();
        
        // 打卡状态和详情
        $status = 1; // 默认正常
        $detail = '';
        
        // 判断打卡类型和工作类型
        if ($setting['work_type'] == 1) {
            // 一次上下班
            if ($type == 1) {
                // 上班打卡
                if (!$inRange) {
                    $status = 2;
                    $detail = '超出打卡范围';
                } else if ($currentTime < date('H:i:s', strtotime("-{$setting['advance_time']} minutes", strtotime($setting['morning_start_time'])))) {
                    $status = 2;
                    $detail = '提前打卡';
                } else if ($currentTime > $setting['morning_start_time']) {
                    $status = 2;
                    $detail = '迟到打卡';
                } else {
                    $detail = '正常上班打卡';
                }
                
                // 更新或创建打卡记录
                if ($record) {
                    // 已有记录，更新
                    Db::name('checkin_record')
                        ->where('id', $record['id'])
                        ->update([
                            'morning_checkin_time' => $now,
                            'morning_checkin_status' => $status,
                            'morning_checkin_detail' => $detail,
                            'checkin_location' => $location,
                            'status' => $status,
                            'detail' => $detail,
                            'update_time' => $now
                        ]);
                } else {
                    // 创建新记录
                    Db::name('checkin_record')->insert([
                        'user_id' => $user['id'],
                        'checkin_date' => $today,
                        'morning_checkin_time' => $now,
                        'morning_checkin_status' => $status,
                        'morning_checkin_detail' => $detail,
                        'checkin_location' => $location,
                        'status' => $status,
                        'detail' => $detail,
                        'create_time' => $now,
                        'update_time' => $now
                    ]);
                }
            } else {
                // 下班打卡
                if (!$record) {
                    return json(['code' => 400, 'msg' => '请先进行上班打卡']);
                }
                
                if (!$inRange) {
                    $status = 2;
                    $detail = '超出打卡范围';
                } else if ($currentTime < $setting['morning_end_time']) {
                    $status = 2;
                    $detail = '提前下班打卡';
                } else if ($currentTime > date('H:i:s', strtotime('+3 hours', strtotime($setting['morning_end_time'])))) {
                    $status = 2;
                    $detail = '超出打卡时间';
                } else {
                    $detail = '正常下班打卡';
                }
                
                // 更新打卡记录
                Db::name('checkin_record')
                    ->where('id', $record['id'])
                    ->update([
                        'morning_checkout_time' => $now,
                        'morning_checkout_status' => $status,
                        'morning_checkout_detail' => $detail,
                        'checkin_location' => $location,
                        'status' => $record['morning_checkin_status'] == 1 && $status == 1 ? 1 : 2,
                        'detail' => $record['morning_checkin_status'] == 1 && $status == 1 ? '上班打卡成功，下班打卡成功' : '打卡异常',
                        'update_time' => $now
                    ]);
            }
        } else {
            // 两次上下班
            $isAfternoon = $currentTime > $setting['afternoon_start_time'] || ($record && $record['morning_checkout_time']);
            
            if ($type == 1) {
                // 上班打卡
                if (!$inRange) {
                    $status = 2;
                    $detail = '超出打卡范围';
                } else if ($isAfternoon) {
                    // 下午上班打卡
                    if ($currentTime < date('H:i:s', strtotime("-{$setting['advance_time']} minutes", strtotime($setting['afternoon_start_time'])))) {
                        $status = 2;
                        $detail = '提前打卡';
                    } else if ($currentTime > $setting['afternoon_start_time']) {
                        $status = 2;
                        $detail = '迟到打卡';
                    } else {
                        $detail = '正常下午上班打卡';
                    }
                    
                    // 更新或创建打卡记录
                    if ($record) {
                        // 已有记录，更新
                        Db::name('checkin_record')
                            ->where('id', $record['id'])
                            ->update([
                                'afternoon_checkin_time' => $now,
                                'afternoon_checkin_status' => $status,
                                'afternoon_checkin_detail' => $detail,
                                'checkin_location' => $location,
                                'status' => $status,
                                'detail' => $detail,
                                'update_time' => $now
                            ]);
                    } else {
                        // 创建新记录
                        Db::name('checkin_record')->insert([
                            'user_id' => $user['id'],
                            'checkin_date' => $today,
                            'afternoon_checkin_time' => $now,
                            'afternoon_checkin_status' => $status,
                            'afternoon_checkin_detail' => $detail,
                            'checkin_location' => $location,
                            'status' => $status,
                            'detail' => $detail,
                            'create_time' => $now,
                            'update_time' => $now
                        ]);
                    }
                } else {
                    // 上午上班打卡
                    if ($currentTime < date('H:i:s', strtotime("-{$setting['advance_time']} minutes", strtotime($setting['morning_start_time'])))) {
                        $status = 2;
                        $detail = '提前打卡';
                    } else if ($currentTime > $setting['morning_start_time']) {
                        $status = 2;
                        $detail = '迟到打卡';
                    } else {
                        $detail = '正常上午上班打卡';
                    }
                    
                    // 更新或创建打卡记录
                    if ($record) {
                        // 已有记录，更新
                        Db::name('checkin_record')
                            ->where('id', $record['id'])
                            ->update([
                                'morning_checkin_time' => $now,
                                'morning_checkin_status' => $status,
                                'morning_checkin_detail' => $detail,
                                'checkin_location' => $location,
                                'status' => $status,
                                'detail' => $detail,
                                'update_time' => $now
                            ]);
                    } else {
                        // 创建新记录
                        Db::name('checkin_record')->insert([
                            'user_id' => $user['id'],
                            'checkin_date' => $today,
                            'morning_checkin_time' => $now,
                            'morning_checkin_status' => $status,
                            'morning_checkin_detail' => $detail,
                            'checkin_location' => $location,
                            'status' => $status,
                            'detail' => $detail,
                            'create_time' => $now,
                            'update_time' => $now
                        ]);
                    }
                }
            } else {
                // 下班打卡
                if (!$record) {
                    return json(['code' => 400, 'msg' => '请先进行上班打卡']);
                }
                
                if (!$inRange) {
                    $status = 2;
                    $detail = '超出打卡范围';
                } else if ($isAfternoon) {
                    // 下午下班打卡
                    if ($currentTime < $setting['afternoon_end_time']) {
                        $status = 2;
                        $detail = '提前下班打卡';
                    } else if ($currentTime > date('H:i:s', strtotime('+3 hours', strtotime($setting['afternoon_end_time'])))) {
                        $status = 2;
                        $detail = '超出打卡时间';
                    } else {
                        $detail = '正常下午下班打卡';
                    }
                    
                    // 更新打卡记录
                    Db::name('checkin_record')
                        ->where('id', $record['id'])
                        ->update([
                            'afternoon_checkout_time' => $now,
                            'afternoon_checkout_status' => $status,
                            'afternoon_checkout_detail' => $detail,
                            'checkin_location' => $location,
                            'status' => $this->calculateFinalStatus($record, $status, 'afternoon'),
                            'detail' => $this->calculateFinalDetail($record, $status, $detail, 'afternoon'),
                            'update_time' => $now
                        ]);
                } else {
                    // 上午下班打卡
                    if ($currentTime < $setting['morning_end_time']) {
                        $status = 2;
                        $detail = '提前下班打卡';
                    } else if ($currentTime > date('H:i:s', strtotime('+3 hours', strtotime($setting['morning_end_time'])))) {
                        $status = 2;
                        $detail = '超出打卡时间';
                    } else {
                        $detail = '正常上午下班打卡';
                    }
                    
                    // 更新打卡记录
                    Db::name('checkin_record')
                        ->where('id', $record['id'])
                        ->update([
                            'morning_checkout_time' => $now,
                            'morning_checkout_status' => $status,
                            'morning_checkout_detail' => $detail,
                            'checkin_location' => $location,
                            'status' => $this->calculateFinalStatus($record, $status, 'morning'),
                            'detail' => $this->calculateFinalDetail($record, $status, $detail, 'morning'),
                            'update_time' => $now
                        ]);
                }
            }
        }
        
        return json([
            'code' => 200,
            'msg' => '打卡成功',
            'data' => [
                'status' => $status,
                'detail' => $detail,
                'time' => $now
            ]
        ]);
    }
    
    /**
     * 获取今日打卡状态
     */
    public function getTodayStatus()
    {
        // 获取当前登录用户
        $user = \app\common\TokenAuth::getUserByToken();
        if (!$user) {
            return json(['code' => 401, 'msg' => '未登录或token已过期']);
        }
        
        // 获取当前日期
        $today = date('Y-m-d');
        
        // 查询今日打卡记录
        $record = Db::name('checkin_record')
            ->where('user_id', $user['id'])
            ->where('checkin_date', $today)
            ->find();
        
        // 获取当前有效的考勤设置
        $setting = Db::name('checkin_setting')
            ->where('status', 1)
            ->order('id', 'desc')
            ->find();
            
        if (!$setting) {
            return json([
                'code' => 404,
                'msg' => '未找到有效的考勤设置'
            ]);
        }
        
        // 构建返回数据
        $data = [
            'workType' => $setting['work_type'],
            'morningStartTime' => $setting['morning_start_time'],
            'morningEndTime' => $setting['morning_end_time'],
            'afternoonStartTime' => $setting['afternoon_start_time'],
            'afternoonEndTime' => $setting['afternoon_end_time'],
            'checkinRecord' => $record ?: null
        ];
        
        return json([
            'code' => 200,
            'msg' => '获取成功',
            'data' => $data
        ]);
    }
    
    /**
     * 计算两个坐标点之间的距离（米）
     * @param string $point1 坐标点1，格式：经度,纬度
     * @param string $point2 坐标点2，格式：经度,纬度
     * @return float 距离（米）
     */
    private function calculateDistance($point1, $point2)
    {
        list($lng1, $lat1) = explode(',', $point1);
        list($lng2, $lat2) = explode(',', $point2);
        
        $lng1 = floatval($lng1);
        $lat1 = floatval($lat1);
        $lng2 = floatval($lng2);
        $lat2 = floatval($lat2);
        
        $radLat1 = deg2rad($lat1);
        $radLat2 = deg2rad($lat2);
        $a = $radLat1 - $radLat2;
        $b = deg2rad($lng1) - deg2rad($lng2);
        
        $s = 2 * asin(sqrt(pow(sin($a/2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b/2), 2)));
        $s = $s * 6378137; // 地球半径
        
        return round($s);
    }
    
    /**
     * 计算最终打卡状态
     * @param array $record 打卡记录
     * @param int $status 当前打卡状态
     * @param string $period 时间段（morning/afternoon）
     * @return int 最终状态
     */
    private function calculateFinalStatus($record, $status, $period)
    {
        if ($period == 'morning') {
            return ($record['morning_checkin_status'] == 1 && $status == 1) ? 1 : 2;
        } else {
            $morningStatus = ($record['morning_checkin_status'] == 1 && $record['morning_checkout_status'] == 1);
            $afternoonStatus = ($record['afternoon_checkin_status'] == 1 && $status == 1);
            
            return ($morningStatus && $afternoonStatus) ? 1 : 2;
        }
    }
    
    /**
     * 计算最终打卡详情
     * @param array $record 打卡记录
     * @param int $status 当前打卡状态
     * @param string $detail 当前打卡详情
     * @param string $period 时间段（morning/afternoon）
     * @return string 最终详情
     */
    private function calculateFinalDetail($record, $status, $detail, $period)
    {
        if ($period == 'morning') {
            if ($record['morning_checkin_status'] == 1 && $status == 1) {
                return '上午上班打卡成功，上午下班打卡成功';
            } else {
                $details = [];
                
                if ($record['morning_checkin_status'] != 1) {
                    $details[] = $record['morning_checkin_detail'];
                }
                
                if ($status != 1) {
                    $details[] = $detail;
                }
                
                return implode('，', $details);
            }
        } else {
            if ($record['morning_checkin_status'] == 1 && $record['morning_checkout_status'] == 1 && 
                $record['afternoon_checkin_status'] == 1 && $status == 1) {
                return '全天打卡成功';
            } else {
                $details = [];
                
                if ($record['morning_checkin_status'] != 1) {
                    $details[] = $record['morning_checkin_detail'];
                }
                
                if ($record['morning_checkout_status'] != 1) {
                    $details[] = $record['morning_checkout_detail'];
                }
                
                if ($record['afternoon_checkin_status'] != 1) {
                    $details[] = $record['afternoon_checkin_detail'];
                }
                
                if ($status != 1) {
                    $details[] = $detail;
                }
                
                return implode('，', $details);
            }
        }
    }
} 